package de.mhu.mandalaui;

import java.util.Iterator;
import java.util.LinkedList;

// TODO synchronize access to the items list

public abstract class AbstractComposite<C extends Attachable,T> extends Component implements Iterable<AbstractComposite.Container<C,T>> {

	private LinkedList<Container<C,T>> items = new LinkedList<Container<C,T>>();
	
	public void add(C item, T options) {
		if (item == null) return;
		items.add(new Container<C,T>(item,options));
		item.componentAttach(this);
	}
	
	@SuppressWarnings("unchecked")
	public T remove(C item) {
		for (Container<C,T> c : items)
			if (c.item.equals(item)) {
				c.item.componentDetach();
				items.remove(c);
				return (T) c.options;
			}
		return null;
	}
	
	public C remove(T options) {
		for (Container<C,T> c : items)
			if (c.options != null && c.options.equals(options)) {
				c.item.componentDetach();
				items.remove(c);
				return c.item;
			}
		return null;
	}
	
	public C remove(int index) {
		if (index < 0 || index >= items.size()) return null;
		Container<C,T> c = items.get(index);
		if (c == null) return null;
		c.item.componentDetach();
		items.remove(c);
		return c.item;
	}

	public C get(int index) {
		if (index < 0 || index >= items.size()) return null;
		return items.get(index).item;
	}
	
	@SuppressWarnings("unchecked")
	public T getOptions(int index) {
		if (index < 0 || index >= items.size()) return null;
		return (T) items.get(index).options;
	}
	
	public Iterator<Container<C,T>> iterator() {
		return items.iterator();
	};
	
	public void removeAll() {
		items.clear();
	}
	
	public static class Container<C,T> {
		private C item;
		private T options;
		
		public Container(C item, T options) {
			this.item = item;
			this.options = options;
		}
		
		public C getItem() {
			return item;
		}
		
		public T getOptions() {
			return options;
		}
	}
	
	@Override
	protected void doInitialize() {
		for (Container<C,T> c : items)
			c.getItem().componentAttach(this);
	}

	@Override
	protected void doDestroy() {
		for (Container<C,T> c : items)
			c.getItem().componentDetach();
	}
	
}

